//
//  ZXPopBaseView.swift
//  ZXPopView
//
//  Created by ZX on 2025/1/27.
//

import UIKit

public extension ZXPopBaseView{
    enum ZXPopViewShowPosition {
        case top
        case bottom
        case left
        case right
        case currentPosition
        case currentPositionWithAnimation
    }
    enum ZXPopViewClosePosition {
        case top
        case bottom
        case left
        case right
        case currentPosition
        case currentPositionWithAnimation
    }
    
    typealias ZXPopBaseViewAnimationDone = (() -> Void)
}

open class ZXPopBaseView: UIView {
    open var isCanClose = true
    open var showTime = 0.3
    open var closeTime = 0.3
    open var maskLayerAlpha = 0.3{
        didSet{
            maskLayerView.alpha = maskLayerAlpha
        }
    }
    
    
    
    public override init(frame: CGRect) {
        super.init(frame: frame)
        self.addSubview(maskLayerView)
        self.addSubview(contentBGView)
        contentBGView.addSubview(contentView)
        configOwnSubViews()
        
    }
    
    required public init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    open func configOwnSubViews() {
        
    }
    
    open override func layoutSubviews() {
        super.layoutSubviews()
        maskLayerView.frame = frame
        contentBGView.frame = frame
    }
    
    open func show(_ from: ZXPopViewShowPosition = .bottom, _ done:ZXPopBaseViewAnimationDone? = nil) {
        self.layoutIfNeeded()
        switch from {
        case .top:
            contentBGView.frame = CGRect(x: 0, y: -height, width: width, height: height)
        case .bottom:
            contentBGView.frame = CGRect(x: 0, y: height, width: width, height: height)
        case .left:
            contentBGView.frame = CGRect(x: -width, y: 0, width: width, height: height)
        case .right:
            contentBGView.frame = CGRect(x: width, y: 0, width: width, height: height)
        case .currentPosition:
            self.contentBGView.frame = CGRect(x: 0, y: 0, width: self.width, height: self.height)
            return
        case .currentPositionWithAnimation:
            self.showInCurrent(done: done)
            return
        }
        self.show(done: done)
    }
    open func close(_ to: ZXPopViewClosePosition = .bottom, done: ZXPopBaseViewAnimationDone? = nil) {
        var newFrame : CGRect = .zero
        switch to {
        case .top:
            newFrame = CGRect(x: 0, y: -height, width: width, height: height)
        case .bottom:
            newFrame = CGRect(x: 0, y: height, width: width, height: height)
        case .left:
            newFrame = CGRect(x: -width, y: 0, width: width, height: height)
        case .right:
            newFrame = CGRect(x: width, y: 0, width: width, height: height)
        case .currentPosition:
            self.isHidden = true
        case .currentPositionWithAnimation:
            self.closeToCurrent(done: done)
            return
        }
        UIView.animate(withDuration: showTime) {
            self.contentBGView.frame = newFrame
        } completion: { finish in
            done?()
            self.removeFromSuperview()
        }
    }
    
    @objc open func closeBGView() {
        if isCanClose {
            self.close()
        }
    }
    
    
    private lazy var maskLayerView: UIView = {
        let view = UIView()
        view.backgroundColor = .black
        view.alpha = maskLayerAlpha
        return view
    }()
    public private(set) lazy var contentBGView: UIView = {
        let view = UIView()
        let tap = UITapGestureRecognizer()
        view.addGestureRecognizer(tap)
        tap.delegate = self
        tap.addTarget(self, action: #selector(closeBGView))
        return view
    }()
    public let contentView = UIView()
}


extension ZXPopBaseView: UIGestureRecognizerDelegate{
    private var width: CGFloat {
        self.contentBGView.frame.size.width
    }
    private var height : CGFloat {
        self.contentBGView.frame.size.height
    }
    public func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool {
        if touch.view != self.contentBGView {
            return false
        }
        return true
    }
}

extension ZXPopBaseView {
    private func showInCurrent(done: ZXPopBaseViewAnimationDone?) {
        let scaleAnimation = CABasicAnimation(keyPath: "transform.scale")
        // 设置动画的起始值
        scaleAnimation.fromValue = 0.01
        // 设置动画的结束值
        scaleAnimation.toValue = 1
        // 设置动画的持续时间
        scaleAnimation.duration = showTime
        
        scaleAnimation.isRemovedOnCompletion = true
        
        // 将动画添加到 contentView 的 layer 上
        contentView.layer.add(scaleAnimation, forKey: "scaleAnimation")
        
        // 动画完成后的操作
        DispatchQueue.main.asyncAfter(deadline:.now() + showTime) {
            // 执行完成后的闭包
            // 移除视图
            done?()
        }
    }
    private func show(done: ZXPopBaseViewAnimationDone?) {
        UIView.animate(withDuration: showTime) {
            self.contentBGView.frame = CGRect(x: 0, y: 0, width: self.width, height: self.height)
        } completion: { finish in
            done?()
        }
    }
}

extension ZXPopBaseView {
    private func closeToCurrent(done: ZXPopBaseViewAnimationDone?) {
        let scaleAnimation = CABasicAnimation(keyPath: "transform.scale")
        // 设置动画的起始值
        scaleAnimation.fromValue = 1.0
        // 设置动画的结束值
        scaleAnimation.toValue = 0.01
        // 设置动画的持续时间
        scaleAnimation.duration = closeTime
        // 设置动画完成后保持最终状态
        scaleAnimation.fillMode = .forwards
        scaleAnimation.isRemovedOnCompletion = false
        
        // 将动画添加到 contentView 的 layer 上
        contentView.layer.add(scaleAnimation, forKey: "scaleAnimation")
        
        // 动画完成后的操作
        DispatchQueue.main.asyncAfter(deadline:.now() + closeTime) {
            // 执行完成后的闭包
            // 移除视图
            done?()
            self.removeFromSuperview()
        }
    }
}

public extension ZXPopBaseView {
    func showFromWindow(_ from: ZXPopViewShowPosition = .bottom,_ done:ZXPopBaseViewAnimationDone? = nil) {
        self.frame = UIScreen.main.bounds
        UIApplication.shared.windows.filter {$0.isKeyWindow}.first?.addSubview(self)
        self.show(from,done)
    }
}

